#include "VNavigationWidget.h"
#include "VWords.h"
#include "VGlobal.h"
#include <QIcon>
#include <QKeyEvent>

VNavigationWidget::VNavigationWidget(QWidget *parent)
	: QWidget(parent)
{
	ui.setupUi(this);
	this->setWindowFlags( Qt::Dialog | Qt::WindowStaysOnTopHint);
	ui.lineEdit->setPlaceholderText("搜索");
	
	this->installEventFilter(this);
	ui.lineEdit->installEventFilter(this);
	init_connect();

}

VNavigationWidget::~VNavigationWidget()
{
}

VNavigationWidget::NavigationData* VNavigationWidget::get_item_data(QListWidgetItem* item){
	return (NavigationData*)(item->data(Qt::UserRole).value<void*>());
}

void VNavigationWidget::slot_set_navigation(QList<NavigationData*> list)
{
	// 释放原本的数据
	for (int i = 0; i < ui.listWidget->count(); i++) {
		auto item = ui.listWidget->item(i);
		auto data = get_item_data(item);
		delete data;
	}
	ui.listWidget->clear();

	foreach(NavigationData * data, list) {
		auto item = new QListWidgetItem(ui.listWidget);
		item->setData(Qt::UserRole, QVariant::fromValue((void*)data));
		item->setText(data->name+QString("---(%1)").arg(data->path));
		item->setIcon(QIcon(get_icon(data->type)));
	}

	if (ui.listWidget->count())
		ui.listWidget->setCurrentRow(0);
}

QString VNavigationWidget::get_icon(int type)
{
	QString result;
	switch (type)
	{
	case VWords::KIND::PROTOTYPE:
		result = VGlobal::icon_path.value("prototype");
		break;
	case VWords::KIND::FUNCTION:
		result = VGlobal::icon_path.value("function");
		break;
	case VWords::KIND::KEYWORD:
		result = VGlobal::icon_path.value("keyword");
		break;
	case VWords::KIND::ENUM:
		result = VGlobal::icon_path.value("enum");
		break;
	case VWords::KIND::ENUMERATOR:
		result = VGlobal::icon_path.value("enumerator");
		break;
	case VWords::KIND::TYPEDEF:
		result = VGlobal::icon_path.value("typedef");
		break;
	case VWords::KIND::STRUCT:
		result = VGlobal::icon_path.value("struct");
		break;
	case VWords::KIND::UNION:
		result = VGlobal::icon_path.value("union");
		break;
	case VWords::KIND::MEMBER:
		result = VGlobal::icon_path.value("menber");
		break;
	case VWords::KIND::MARCO:
		result = VGlobal::icon_path.value("define");
		break;
	case VWords::KIND::PARAMETER:
		result = VGlobal::icon_path.value("parameter");
		break;
	case VWords::KIND::LOCAL:
		result = VGlobal::icon_path.value("local");
		break;
	case VWords::KIND::VARIABLE:
		result = VGlobal::icon_path.value("global");
		break;
	case VWords::KIND::FILE:
		result = VGlobal::icon_path.value("file_h");
		break;
	case VWords::KIND::FOLDER:
		result = VGlobal::icon_path.value("folder");
		break;
	case VWords::KIND::TEMPLATE:
		result = VGlobal::icon_path.value("template");
		break;
	case VWords::KIND::LABEL:
		result = VGlobal::icon_path.value("label");
		break;
	default:
		break;
	}
	return result;
}

bool VNavigationWidget::eventFilter(QObject* watched, QEvent* event)
{
	if (event->type() == QEvent::FocusOut) {
		if (this->isActiveWindow() == false) {
			ui.lineEdit->clear();
			this->hide();
		}
	}

	if (watched == ui.lineEdit) {
		if (event->type() == QEvent::KeyPress) {
			QKeyEvent* key_event = static_cast<QKeyEvent*>(event);
			if (key_event->key() == Qt::Key_Up) {
				int row = ui.listWidget->currentRow();
				if (row > 0)
					ui.listWidget->setCurrentRow(--row);
			}else if (key_event->key() == Qt::Key_Down) {
				int row = ui.listWidget->currentRow();
				if (row < ui.listWidget->count() - 1)
					ui.listWidget->setCurrentRow(++row);
			}else if (key_event->key() == Qt::Key_Escape) {
				ui.lineEdit->clear();
				this->hide();
			}else if (key_event->key() == Qt::Key_Tab) {
				int index = ui.comboBox->currentIndex();
				ui.comboBox->setCurrentIndex((++index) % 3);
			}else if (key_event->key() == Qt::Key_Enter || 
				key_event->key() == Qt::Key_Return) {
				auto item = ui.listWidget->currentItem();
				if (item != nullptr) {
					auto data = get_item_data(item);
					if (data->type == VWords::KIND::FILE) {
						emit signal_open_file(data->path);
					}else {
						emit signal_jump(data->path, data->line);
					}

					ui.lineEdit->clear();
					this->hide();
				}
			}
		}
	}
	return QWidget::eventFilter(watched, event);
}

void VNavigationWidget::init_connect()
{
	connect(ui.lineEdit, &QLineEdit::textChanged, [this]() {
		emit signal_navigation(this->ui.lineEdit->text(), ui.comboBox->currentIndex() + 1);
	});
	connect(ui.comboBox, static_cast<void(QComboBox::*)(int)>(&QComboBox::currentIndexChanged), [this]() {
		emit signal_navigation(this->ui.lineEdit->text(), ui.comboBox->currentIndex() + 1);
	});
}

